package SquareFighters;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;

/**
 *
 * @author Someperson1
 */
public final class Field extends JPanel {

    int width, height;
    int[] pos = new int[2];
    int[] move = new int[2];
    int mframe = -1, sframe = -1, hframe = -1;
    int dir;
    int level;
    int score;
    final int bossinterval = 10;
    ArrayList<Enemy> enemy;
    ArrayList<Boss> boss;
    Actor actor = new Actor(this);
    Timer timer;
    boolean magic;
    boolean fire;
    boolean speed;
    boolean pause;
    private int spframe;
    boolean bossround;

    public Field() {
        pos[0] = 400;
        pos[1] = 325;
        enemy = new ArrayList();
        boss = new ArrayList();
        newGame();
        ActionListener listener = new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                if (pos[0] < 0) {
                    pos[0] = 0;
                }
                if (pos[0] > getWidth() - 1) {
                    pos[0] = getWidth() - 1;
                }
                if (pos[1] < 15) {
                    pos[1] = 15;
                }
                if (pos[1] > getHeight() - 1) {
                    pos[1] = getHeight() - 1;
                }
                if (level == 43) {
                    timer = new Timer(15, this);
                }
                repaint();
            }
        };

        timer = new Timer(15, listener);

        addMouseListener(
                new MouseAdapter() {

                    @Override
                    public void mousePressed(MouseEvent evt) {
                        requestFocus();
                        if (actor.getHealth() == 0) {
                            newGame();
                            timer.start();
                        }
                    }
                });

        addFocusListener(
                new FocusListener() {

                    @Override
                    public void focusGained(FocusEvent evt) {
                        timer.start();
                        repaint();
                    }

                    @Override
                    public void focusLost(FocusEvent evt) {
                        timer.stop();
                        repaint();
                    }
                });

        addKeyListener(
                new KeyAdapter() {

                    @Override
                    public void keyPressed(KeyEvent evt) {
                        int key = evt.getKeyCode();
                        if (key == KeyEvent.VK_A) {
                            move[0] = -1;
                        } else if (key == KeyEvent.VK_D) {
                            move[0] = 1;
                        } else if (key == KeyEvent.VK_W) {
                            move[1] = -1;
                        } else if (key == KeyEvent.VK_S) {
                            move[1] = 1;
                        } else if (key == KeyEvent.VK_E) {
                            magic = !magic;
                        } else if (key == KeyEvent.VK_UP) {
                            fire = true;
                            dir = 0;
                        } else if (key == KeyEvent.VK_RIGHT) {
                            fire = true;
                            dir = 1;
                        } else if (key == KeyEvent.VK_DOWN) {
                            fire = true;
                            dir = 2;
                        } else if (key == KeyEvent.VK_LEFT) {
                            fire = true;
                            dir = 3;
                        } else if (key == KeyEvent.VK_SPACE) {
                            if (spframe >= 0) {
                                speed = true;
                            }
                        } else if (key == KeyEvent.VK_P) {
                            if (pause) {
                                timer.stop();
                                pause = false;
                            } else {
                                timer.start();
                                pause = true;
                            }
                        }
                    }

                    @Override
                    public void keyReleased(KeyEvent evt) {
                        int key = evt.getKeyCode();
                        if (key == KeyEvent.VK_A
                                || key == KeyEvent.VK_D) {
                            move[0] = 0;
                        } else if (key == KeyEvent.VK_W
                                || key == KeyEvent.VK_S) {
                            move[1] = 0;
                        } else if (key == KeyEvent.VK_UP
                                || key == KeyEvent.VK_RIGHT
                                || key == KeyEvent.VK_DOWN
                                || key == KeyEvent.VK_LEFT) {
                            fire = false;
                        } else if (key == KeyEvent.VK_SPACE) {
                            speed = false;
                        }
                    }
                });
    }

    public void moveActor() {
        int x;
        if (actor.getStr() <= 2) {
            speed = false;
            spframe = -actor.getMaxStr() / 2;
        }
        if (speed) {
            x = 6;
            actor.modStr(-2);
        } else {
            x = 3;
            spframe++;
        }
        for (int i = 0; i < move.length; i++) {
            if (move[i] == 1) {
                pos[i] += x;
            } else if (move[i] == -1) {
                pos[i] -= x;
            }
        }
    }

    public void newGame() {
        enemy.clear();
        boss.clear();
        level = 0;
        nextRound();
        score = 0;
        actor.modMaxHealth(-100);
        actor.modMaxMagic(-100);
        actor.modMaxStr(-100);
        actor.usem = false;
        actor.useh = false;
        actor.uses = false;
        magic = false;
        hframe = 0;
        mframe = 0;
        sframe = 0;
    }

    public void fire() {
        if (magic && !actor.usem) {
            if (actor.getMagic() >= 5) {
                actor.modMagic(-5);
                mframe = -20;
                actor.usem = true;
            }
        } else if (!magic && !actor.uses) {
            if (actor.getStr() >= 5) {
                actor.modStr(-5);
                sframe = -13;
                actor.uses = true;
            }
        }
    }

    public void nextRound() {
        level++;
        score += 100 * level;
        int x = 10;
        int a = (int) (Math.random() * 3);
        if (level % bossinterval == 0) {
            bossround = true;
            x *= (level / bossinterval);
        } else {
            bossround = false;
        }
        if (a == 0) {
            actor.modMaxHealth(x);
            actor.modHealth(x);
        } else if (a == 1) {
            actor.modMaxMagic(x);
            actor.modMagic(x);
        } else if (a == 2) {
            actor.modMaxStr(x);
            actor.modStr(x);
        }
        if (level == 41) {
            for (int i = 0; i < 4; i++) {
                boss.add(new Boss(this));
            }
            for (int i = 0; i < 10; i++) {
                enemy.add(new Enemy(this));
            }
        } else if (level == 42) {
            for (int i = 0; i < 6; i++) {
                boss.add(new Boss(this));
            }
            for (int i = 0; i < 15; i++) {
                enemy.add(new Enemy(this));
            }
        } else if (bossround) {
            for (int i = 0; i < (level / bossinterval); i++) {
                boss.add(new Boss(this));
            }
        } else {
            for (int i = 0; i < level; i++) {
                enemy.add(new Enemy(this));
            }
        }
    }

    public void drawEnemy(Graphics g) {
        if (level == 41 || level == 42) {
            if (boss.isEmpty() && enemy.isEmpty()) {
                nextRound();
            }
            for (int i = 0; i < boss.size(); i++) {
                boss.get(i).draw(g);
                if (boss.get(i).h <= 0) {
                    boss.remove(i);
                }
            }
            for (int i = 0; i < enemy.size(); i++) {
                enemy.get(i).draw(g);
                if (enemy.get(i).h <= 0) {
                    enemy.remove(i);
                }
            }
        } else if (bossround) {
            if (boss.isEmpty()) {
                nextRound();
            }
            for (int i = 0; i < boss.size(); i++) {
                boss.get(i).draw(g);
                if (boss.get(i).h <= 0) {
                    boss.remove(i);
                }
            }
        } else {
            if (enemy.isEmpty()) {
                nextRound();
            }
            for (int i = 0; i < enemy.size(); i++) {
                enemy.get(i).draw(g);
                if (enemy.get(i).h <= 0) {
                    enemy.remove(i);
                }
            }
        }
    }

    public void nextFrame() {
        if (mframe == 1) {
            actor.modMagic(1);
            mframe = 0;
        } else {
            mframe++;
        }
        if (sframe == 0) {
            actor.modStr(1);
        } else {
            sframe++;
        }
        if (hframe == 4) {
            actor.modHealth(1);
            hframe = 0;
        } else {
            hframe++;
        }
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        moveActor();
        width = getWidth();
        height = getHeight();
        g.setColor(Color.BLACK);
        g.fillRect(0, 0, width, height);
        if (actor.getHealth() > 0) {
            actor.draw(g, width / 2, pos[0], pos[1], dir);
            drawEnemy(g);
            nextFrame();
            if (fire) {
                fire();
            }
            if (hasFocus()) {
                g.setColor(Color.RED);
                g.drawString("Score " + score, 30, 30);
                g.drawString("level " + level, 30, 50);
                if (level > 42) {
                    g.drawString("YOU LOST THE GAME", 30, 70);
                }
                g.setColor(Color.DARK_GRAY);
            } else {
                g.setColor(Color.RED);
                g.drawString("CLICK TO ACTIVATE", 20, 30);
                g.setColor(Color.WHITE);
            }
            g.drawRect(0, 14, width - 1, height - 15);
            g.drawRect(1, 15, width - 3, height - 17);
        } else {
            g.setColor(Color.RED);
            g.drawString("YOU LOST THE GAME", 275, 260);
            g.drawString("Got to level " + level, 275, 280);
            g.drawString("Score " + score, 275, 300);
            g.drawString("Click for New Game", 275, 320);
            timer.stop();
        }
    }
}
